import axios, { InternalAxiosRequestConfig } from "axios";
import qs from "qs";
import { useAuthStore } from "../../store";
import router from "../../router";
// 用于存储请求的Map对象，key为请求的url+params+method的组合，value为请求的CancelToken源
const pendingRequests = new Map();
// 白名单
const whiteList: string[] = ["/api/auth/login", "/api/auth/register"];

// 判断是否在白名单中
const isInWhiteList = (url: string) => {
  return whiteList.some((white) => url.startsWith(white));
};
// 添加请求
const addPendingRequest = (config: InternalAxiosRequestConfig<any>) => {
  const url = [
    config.method,
    config.url,
    qs.stringify(config.params), // 你可能需要安装qs库来处理params: npm install qs
    qs.stringify(config.data),
  ].join("&");
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!pendingRequests.has(url)) {
        // 如果pendingRequests中没有这个url，就添加进去
        pendingRequests.set(url, cancel);
      } else {
        // 如果pendingRequests中有这个url，就取消之前的请求，并重新设置cancelToken
        const previousCancel = pendingRequests.get(url);
        previousCancel("Request canceled"); // 取消之前的请求
        pendingRequests.set(url, cancel); // 重置cancelToken
      }
    });
};

// 移除请求
const removePendingRequest = (config: InternalAxiosRequestConfig<any>) => {
  const url = [
    config.method,
    config.url,
    qs.stringify(config.params),
    qs.stringify(config.data),
  ].join("&");
  if (pendingRequests.has(url)) {
    // 如果在pendingRequests中存在这个请求，就移除它
    const cancel = pendingRequests.get(url);
    cancel("Request finished"); // 请求完成后取消该请求，避免后续操作再次取消该请求（虽然理论上不应该发生）
    pendingRequests.delete(url);
  }
};

// 创建axios实例并添加拦截器来处理请求和响应
const service = axios.create({
  baseURL: "/api", // 你可以在这里设置默认的baseURL
  timeout: 5000, // 你可以在这里设置默认的超时时间
  headers: {
    "Content-Type": "application/json;charset=UTF-8",
  },
  withCredentials: true,
  // 你可以在这里设置默认的axios配置，例如baseURL等
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 判断请求路径是否在白名单中
    const url = config.url || "";
    if (!isInWhiteList(url)) {
      const token = useAuthStore().getToken();
      if (token) {
        config.headers["Authorization"] = `Bearer ${token}`;
      } else {
        // 如果需要token但没有token，可以在这里处理，比如跳转到登录页
        console.warn("No token found");
        router.push("/login");
        // 可以选择抛出错误或其他处理方式
        // return Promise.reject(new Error('No token found'));
      }
    }

    addPendingRequest(config);
    return config;
  },
  (error) => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    removePendingRequest(response.config); // 在请求完成后从pendingRequests中移除请求
    return response;
  },
  (error) => {
    // 如果是取消请求的错误，则不进行错误处理
    if (axios.isCancel(error)) {
      console.log("Request canceled", error.message);
      return Promise.resolve("Request canceled"); // 你可以根据需要修改这里的处理方式，例如返回一个特定的错误对象等。
    } else {
      // 处理其他响应错误
      return Promise.reject(error);
    }
  }
);

export default service; // 导出封装后的axios实例以供其他文件使用。
